﻿using AnesSystem.Models;
using AnesSystem.Services;
using AnesSystem.ViewModels;
using Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Xml;

namespace AnesSystem.Controls
{
    /// <summary>
    /// 普通表单不具有逻辑得控件
    /// </summary>
    public class CustomCommonTableCtrl : BaseTableControl
    {

        #region Variables

        List<ClassHelper.CustPropertyInfo> _listCpi = new List<ClassHelper.CustPropertyInfo>();
        Dictionary<string, BaseCustomCtrl> _baseCustomCtrls = new Dictionary<string, BaseCustomCtrl>();
        string upField = "";
        int index = 0;
        bool isCeated = false;
        #endregion

        #region Constructor

        public CustomCommonTableCtrl()
        {
            this.Margin = new Thickness(0, 0, 0, 0);
            this.Loaded += CustomCommonTableCtrl_Loaded;
        }

        #endregion

        #region Properties


        public string CtrlName { get; set; }

        public string TableName { get; set; }

        public List<ClassHelper.CustPropertyInfo> ListCpi
        {
            get
            {
                return _listCpi;
            }

            set
            {
                _listCpi = value;
            }
        }

        public Dictionary<string, BaseCustomCtrl> BaseCustomCtrls
        {
            get
            {
                return _baseCustomCtrls;
            }

            set
            {
                _baseCustomCtrls = value;
            }
        }

        #endregion

        #region Event

        #endregion

        #region Private Methods

        private void FindChildren(Panel parent)
        {
            foreach (var child in parent.Children)
            {
                if (child is Panel)
                {
                    FindChildren(child as Panel);
                }
                else
                {
                    if (child is BindTextCtrl)
                    {
                        ClassHelper.CustPropertyInfo cpi = new ClassHelper.CustPropertyInfo("System.String", (child as BindTextCtrl).FieldName);
                        ListCpi.Add(cpi);
                    }
                    if (child is BaseCustomCtrl)
                    {
                        ClassHelper.CustPropertyInfo cpi = new ClassHelper.CustPropertyInfo("System.String", (child as BaseCustomCtrl).FieldName);
                        ListCpi.Add(cpi);
                        BaseCustomCtrls.Add(cpi.PropertyName, (child as BaseCustomCtrl));
                    }
                }
            }
        }

        private void FillObjByDBValue()
        {
            CommonTableModel table = DataManager.Instance.CurrentPatientLink.Tables[this.TableName];
            foreach (var ctrl in BaseCustomCtrls.Values)
            {
                ctrl.Value = table.GetType().GetProperty(ctrl.FieldName).GetValue(table);
            }
        }

        private void CreateXmlContent(CommonTableModel tableModel, List<ClassHelper.CustPropertyInfo> listCpi)
        {
            XmlDocument doc = new XmlDocument();
            XmlElement root = doc.CreateElement("TableName");
            root.SetAttribute("value", TableName);
            foreach (var item in listCpi)
            {
                if (!BaseCustomCtrls.ContainsKey(item.PropertyName))
                    continue;
                XmlElement node = doc.CreateElement(item.PropertyName);
                root.AppendChild(node);
            }
            doc.AppendChild(root);
            tableModel.TableName = TableName;
            tableModel.XmlContent = string.Format("<?xml version=\"1.0\" encoding=\"utf - 8\"?>{0}", doc.InnerXml);
        }

        private void FillItemValue(CustomCommonTableCtrl ctrl)
        {
            if (ctrl.ListCpi.Count == 0)
                FindChildren(ctrl.Content as Visual, ctrl);
            if (DataManager.Instance.CurrentPatientLink == null) return;
            if (DataManager.Instance.CurrentPatientLink.Tables == null)
            {
                DataManager.Instance.CurrentPatientLink.Tables = new Dictionary<string, CommonTableModel>();
            }
            CommonTableModel tableModel = new CommonTableModel();
            if (!DataManager.Instance.CurrentPatientLink.Tables.ContainsKey(ctrl.TableName))
            {
                DataManager.Instance.CurrentPatientLink.Tables.Add(ctrl.TableName, tableModel);
                CreateXmlContent(tableModel, ctrl.ListCpi);
                SaveOper2DB();//新开表单实时存入数据库(表单填值获取数据库最新病人信息)
            }
            else
            {
                tableModel = DataManager.Instance.CurrentPatientLink.Tables[ctrl.TableName];

                if (string.IsNullOrEmpty(tableModel.XmlContent))
                {
                    CreateXmlContent(tableModel, ctrl.ListCpi);
                }
                else
                {
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(tableModel.XmlContent);
                    XmlElement root = (XmlElement)doc.GetElementsByTagName("TableName")[0];
                    foreach (var item in ctrl.ListCpi)
                    {
                        try
                        {
                            XmlNodeList nodeList = root.GetElementsByTagName(item.PropertyName);
                            if (nodeList.Count == 0)
                            {
                                continue;
                            }
 //                           if (!string.IsNullOrEmpty(nodeList[0].InnerXml))
                                ctrl.BaseCustomCtrls[item.PropertyName].Value = nodeList[0].InnerXml;
                        }
                        catch (Exception ex)
                        {
                            Common.LogHelper.Error("SysMainWinViewModel", ex);
                        }
                    }
                    isCeated = true;
                }
            }
        }

        private void SaveOper2DB()
        {
            PatientLinkService.Instance.AddUpdate(DataManager.Instance.CurrentPatientLink);
        }

        #endregion

        #region Public/Protected Methods

        protected void FindChildren(Visual parent, CustomCommonTableCtrl tableCtrl)
        {
            int count = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < count; i++)
            {
                Visual childVisual = (Visual)VisualTreeHelper.GetChild(parent, i);
                if (childVisual != null)
                {
                    if (childVisual != null)
                    {
                        if (childVisual is BindCtrl)
                        {
                            //ClassHelper.CustPropertyInfo cpi = new ClassHelper.CustPropertyInfo("System.String", (childVisual as BindTextCtrl).FieldName);
                            //cpi.PropertyValue = (childVisual as BindTextCtrl).Text;
                            //ListCpi.Add(cpi);
                            //index++;
                        }
                        else if (childVisual is BaseCustomCtrl)
                        {
                            BaseCustomCtrl ctrl = childVisual as BaseCustomCtrl;
                            if (string.IsNullOrEmpty(ctrl.FieldName))
                            {
                                ctrl.FieldName = "ctrl" + index;
                            }
                            ClassHelper.CustPropertyInfo cpi = new ClassHelper.CustPropertyInfo("System.String", ctrl.FieldName);
                            cpi.PropertyValue = ctrl.Value;
                            tableCtrl.ListCpi.Add(cpi);
                            ctrl.ClassName = tableCtrl.TableName;
                            if (!tableCtrl.BaseCustomCtrls.ContainsKey(cpi.PropertyName))
                                tableCtrl.BaseCustomCtrls.Add(cpi.PropertyName, ctrl);
                            else
                                Common.LogHelper.Error(this.GetType(), "字段重复：" + cpi.PropertyName);
                            index++;
                        }
                    }
                    FindChildren(childVisual, tableCtrl);
                }
            }
        }

        public void FillValue()
        {
            if (CusContent is TabControl)
            {
                TableItems.Clear();
                TabControl tab = CusContent as TabControl;
                foreach (TabItem item in tab.Items)
                {
                    if (item.Content is CustomCommonTableCtrl)
                    {
                        FillItemValue(item.Content as CustomCommonTableCtrl);
                        TableItems.Add(item.Content as CustomCommonTableCtrl);
                    }
                }
            }
            else
            {
                FillItemValue(this);
            }

        }

        /// <summary>
        /// 获取当前表单字段的值
        /// </summary>
        /// <param name="p">手术</param>
        /// <param name="tableName">某张表单</param>
        /// <param name="fields">需要获取值的字段集合</param>
        /// <returns></returns>
        public List<string> GetCurPatientXMLTableValue(params string[] fields)
        {
            try
            {
                if (string.IsNullOrEmpty(TableName)) return null;
                return DataManager.Instance.GetCurPatientXMLTableValue(TableName, fields);
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
                return null;
            }
        }

        /// <summary>
        /// 获取当前表单字段的值
        /// </summary>
        /// <param name="p">手术</param>
        /// <param name="tableName">某张表单</param>
        /// <param name="field">需要获取值的字段</param>
        /// <returns></returns>
        public string GetCurPatientXMLTableValue(string field)
        {
            try
            {
                if (string.IsNullOrEmpty(TableName)) return null;
                return DataManager.Instance.GetCurPatientXMLTableValue(TableName, field);
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
                return null;
            }
        }

        /// <summary>
        /// 填充xml表单的值
        /// </summary>
        /// <param name="className"></param>
        /// <param name="fieldName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool FillXMLTableValue(string fieldName, string value)
        {
            try
            {
                DataManager.Instance.FillXMLTableValue(TableName, fieldName, value);
                return true;
            }
            catch (Exception ex)
            {
                Common.LogHelper.Error(this.GetType(), ex);
                return false;
            }
        }

        /// <summary>
        /// 填充控件界面显示的值
        /// </summary>
        /// <param name="fieldAndValues"></param>
        /// <returns></returns>
        public bool FillCtrlValue(Dictionary<string, object> fieldAndValues)
        {
            return DataManager.Instance.FillCtrlValue(fieldAndValues);
        }

        /// <summary>
        /// 填充和保存xml表单的值
        /// </summary>
        /// <param name="fieldAndValues"></param>
        /// <returns></returns>
        public bool FillAndSaveXMLTableValue(Dictionary<string, object> fieldAndValues)
        {
            return DataManager.Instance.FillAndSaveXMLTableValue(fieldAndValues);
        }

        public override void Refesh()
        {
            //DataManager.Instance.RefCurrentPatientLink();
            if (DataManager.Instance.CurrentPatientLink!=null)
            {
                Mapper(PatientLinkService.Instance.GetObjById(DataManager.Instance.CurrentPatientLink.Id.ToString()), DataManager.Instance.CurrentPatientLink);
            }
            isCeated = false;
            FillValue();
        }

        public void Mapper<PatientLinkModel>(PatientLinkModel newObj, PatientLinkModel oldObj)
        {
            try
            {
                Type Typeb = newObj.GetType();
                Type Typea = typeof(PatientLinkModel);
                foreach (PropertyInfo sp in Typeb.GetProperties())  
                {
                    if (sp.CanWrite)
                    {
                        sp.SetValue(oldObj, sp.GetValue(newObj, null), null);  
                    }
                }
            }
            catch (Exception ex)
            {
                Common.LogHelper.Error(this.GetType(), ex);
            }
        }

        #endregion

        #region EventHandlers

        private void CustomCommonTableCtrl_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
    //        Refesh();
            DataManager.Instance.TableHeaderCtrl.ViewModel.DefaultDisplayModel = 1;
        }

        #endregion

    }
}
